package com.atguigu.gulimail.auth.controller;

import com.atguigu.common.constant.AuthServerConstant;
import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import com.atguigu.gulimail.auth.feign.MemberFeignService;
import com.atguigu.gulimail.auth.feign.ThirdPartyFeignService;
import com.atguigu.gulimail.auth.vo.RegistVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Controller
public class RegistController {
    @Autowired
    ThirdPartyFeignService smsFeignService;

    @Autowired
    RedisTemplate jsonRedisTemplate;

    @Autowired
    MemberFeignService memberFeignService;

    @GetMapping("/sendCode")
    public R sendCode(@RequestParam("phone")String phone){
        //防止刷新页面后再次发送验证码。   在redis中保存。
        String s = (String) jsonRedisTemplate.opsForValue().get(AuthServerConstant.SMS_REDIS_CACHE_PREFIX + phone);
        if(!StringUtils.isEmpty(s)){
            String[] strings = s.split("_");

            if(System.currentTimeMillis()-Long.parseLong(strings[1])<60*1000){
                return  R.error(BizCodeEnum.SMS_CODE_EXCEPTION.getCode(), BizCodeEnum.SMS_CODE_EXCEPTION.getMsg());
            }
        }

        String code = UUID.randomUUID().toString().substring(0, 5);
        String redisCode= code+"_"+System.currentTimeMillis();

        jsonRedisTemplate.opsForValue().set(AuthServerConstant.SMS_REDIS_CACHE_PREFIX+phone,redisCode,10, TimeUnit.MINUTES);


        smsFeignService.sendCode(phone, code);

        return R.ok();
    }

            //TODO  还要考虑分布式session中 怎么保存数据
    //这里有个逻辑是 只要有异常。 那么就要把redis中的数据给删除了。
    @PostMapping("/regist")
    public String regist(@Valid  RegistVo registVo, BindingResult bindingResult, RedirectAttributes redirectAttributes){
        System.out.println("???????????????");
        //首先判定有没有异常。如果没有异常。那么就重定向到登录页面。 如果有异常。那么就转发到注册页面
        if(bindingResult.getFieldErrors()!=null&&bindingResult.getFieldErrors().size()>0){
           // jsonRedisTemplate.delete(AuthServerConstant.SMS_REDIS_CACHE_PREFIX + registVo.getPhone());
            Map<String, String> errorsMap = bindingResult.getFieldErrors().
                    stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage,(item1,item2)->item1));
                //前端页面 $("errors").字段名 才获取的是错误信息
            //model.addAttribute("errors", errors);
            //一闪而过。
                redirectAttributes.addFlashAttribute("errors", errorsMap);
            //Request method 'POST' not supported  因为前端发送过来的是post请求。而forward:/reg.html是一个get请求。
            //post请求不能转到Get请求。
//            return "forward:/reg.html";
            //防止表单重复提交。那么我就要用redirect
            //但是如果直接 重定向。  那么就会使用当前域名重定向。  我想用的是auth.gulimail.com
            //使用重定向后。model的权限就不在了 model应该只能向request域中保存数据
            return "redirect:http://auth.gulimail.com/reg.html";
        }else{
            //否则 判定验证码
            String code = registVo.getCode();
            String s = (String) jsonRedisTemplate.opsForValue().get(AuthServerConstant.SMS_REDIS_CACHE_PREFIX + registVo.getPhone());
            if(!StringUtils.isEmpty(s)){
                //如果不为空。
                if(code.equals(s.split("_")[0])){
                    //如果相等
                    //首先删除验证码。
                    jsonRedisTemplate.delete(AuthServerConstant.SMS_REDIS_CACHE_PREFIX + registVo.getPhone());

                    //调用远程服务注册功能。
                    //member 微服务。
                    R regist = memberFeignService.regist(registVo);
                    if(regist.getCode()==0){
                        //如果等于0 则表示注册成功。
                        return "redirect:http://auth.gulimail.com/login.html";
                    }else{
                        Map<String, String> errorsMap =new HashMap<>();
                        String msg = regist.getMsg();
                        errorsMap.put("faild",msg);
                        redirectAttributes.addFlashAttribute("errors", errorsMap);
                        return "redirect:http://auth.gulimail.com/reg.html";
                    }


                }else{
                    Map<String,String> errors=new HashMap<>();
                    errors.put("code", "验证码错误");
                    redirectAttributes.addFlashAttribute("errors", errors);
                    return "redirect:http://auth.gulimail.com/reg.html";
                }
            }else{
               // jsonRedisTemplate.delete(AuthServerConstant.SMS_REDIS_CACHE_PREFIX + registVo.getPhone());
                Map<String,String> errors=new HashMap<>();
                errors.put("code", "验证码错误");
                redirectAttributes.addFlashAttribute("errors", errors);
                return "redirect:http://auth.gulimail.com/reg.html";
            }
        }


    }

}
